#include "head.h"
pCmdWord HashTable[MAXKEY] = {0};

int main()
{
    // 建立与服务端的TCP连接
    int sockfd;
    tcpInit("./config/client_1.conf", &sockfd);
    printf("connection established!\n");
    // 用户登录
    char user_name[256] = {0};
    user_login(sockfd, user_name);
    char pwd[512] = {0};
    strcpy(pwd, "~/");
    // 初始化用于存储命令类型的哈希表
    int cmdword_length = sizeof(cmdword) / sizeof(CmdWord);
    init_hash(cmdword, cmdword_length);
    cmd_t CmdtoSend;
    // 监听STDIN，解析命令
    fd_set rdset;
    char buf[4096];
    // printf("enter a command:\n");
    while (1)
    {
        printf("\33[1m\33[32m[%s@ %s]: \33[0m", user_name, pwd);
        fflush(stdout);
        fflush(stdin);
        FD_ZERO(&rdset);
        FD_SET(STDIN_FILENO, &rdset);
        select(STDIN_FILENO + 1, &rdset, NULL, NULL, NULL);
        if (FD_ISSET(STDIN_FILENO, &rdset))
        { // 标准输入就绪，读取输入指令，解析命令，并发送给服务端
            bzero(buf, sizeof(buf));
            bzero(&CmdtoSend, sizeof(cmd_t));
            int ret = read(STDIN_FILENO, buf, sizeof(buf));
            if (0 == ret)
            { // 如果输入Ctrl+D则发送token为-1的退出命令，并关闭客户端
                CmdtoSend.token = -1;
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                printf("Goodbye !\n");
                break;
            }
            ret = cmd_anal(buf, ret, &CmdtoSend);
            if (ret == -1)
            {
                // 无效指令，无视
                continue;
            }
            if (CmdtoSend.token == CMD_CD)
            {
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                int check = 0;
                recv(sockfd, &check, sizeof(check), MSG_WAITALL);
                if (check != 0)
                {
                    printf("wrong command!\n");
                    continue;
                }
                train_t train;
                bzero(&train, sizeof(train));
                recv(sockfd, &train.length, sizeof(train.length), MSG_WAITALL);
                recv(sockfd, train.data, train.length, MSG_WAITALL);
                strcpy(pwd, train.data);
            }
            if (CmdtoSend.token == CMD_LS)
            {
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                int check = 0;
                recv(sockfd, &check, sizeof(int), MSG_WAITALL);
                if (check == 1)
                {
                    printf("wrong path!\n");
                    continue;
                }
                train_t train;
                while (1)
                {
                    bzero(&train, sizeof(train_t));
                    recv(sockfd, &train.length, sizeof(train.length), MSG_WAITALL);
                    if (train.length == 0)
                    {
                        break;
                    }
                    recv(sockfd, train.data, train.length, MSG_WAITALL);
                    printf("%s\t", train.data);
                }
                printf("\n");
            }
            if (CmdtoSend.token == CMD_PWD)
            {
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                char pwd[1024] = {0};
                recv(sockfd, pwd, sizeof(pwd), 0);
                printf("%s\n", pwd);
            }
            if (CmdtoSend.token == CMD_MKDIR)
            {
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                int check = 0;
                recv(sockfd, &check, sizeof(check), 0);
                if (check != 0)
                {
                    printf("fail to mkdir!\n");
                    continue;
                }
                printf("dir has been created!\n");
            }
            if (CmdtoSend.token == CMD_REMOVE)
            {
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                int check = 0;
                recv(sockfd, &check, sizeof(check), MSG_WAITALL);
                if (check != 0)
                {
                    printf("fail to remove!\n");
                    continue;
                }
                printf("target has been removed!\n");
            }
            if (CmdtoSend.token == CMD_GETS)
            {
                // 断点续传
                int flag = isunfinished(CmdtoSend);
                if (1 == flag)
                { // 获取已传文件大小
                    char fileName[256] = {0};
                    strcpy(fileName, CmdtoSend.object);
                    CmdtoSend.offset = get_offset(fileName);
                }
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                // 接收文件
                recvFile(sockfd, CmdtoSend.offset);
            }
            if (CmdtoSend.token == CMD_PUTS)
            {
                send(sockfd, &CmdtoSend, sizeof(cmd_t), MSG_NOSIGNAL);
                usleep(100000);//阻塞客户端0.1s确保服务端先进行listen
                int sockfd_2;
                tcpInit("./config/client_2.conf", &sockfd_2);
                printf("the second connection established!\n");
                transFile(sockfd_2, CmdtoSend);
                printf("upload succeeded\n");
                close(sockfd_2);
            }
        }
    }
    close(sockfd);
}